package builders;

import backbone.IBuildable;
import backbone.IPaintable;
import backbone.IUpdatable;
import entities.Bar;
import entities.LineObject;
import entities.Muscle;
import entities.Spring;
import java.util.LinkedList;
import main.Simulation;

/**
 * Builds line Objects
 * @author Paul
 * @author Lance
 *
 */
public class LineObjectBuilder implements IBuildable {

    private PointObjectBuilder myPointObjectBuilder;
    
    /**
     * Constructs a particular line object.
     * @param pointObjectBuilder The point objects that the line
     * object should be joined to.
     */
    public LineObjectBuilder(PointObjectBuilder pointObjectBuilder) {
        myPointObjectBuilder = pointObjectBuilder;
    }
    
    /**
     * Builds the object from a list of properties and adds 
     * it to a particular simulation.
     */
    public void build(Simulation sim, LinkedList<Double> properties) {
        LineObject newLineObject;
        int m1 = (int)(double)properties.poll(); 
        int m2 = (int)(double)properties.poll();
        double restLength = properties.poll();
        double ks = properties.poll();
        if (!properties.isEmpty()) {
            double amp = properties.poll();
            newLineObject = new Muscle(myPointObjectBuilder.getPointObject(m1),
                    myPointObjectBuilder.getPointObject(m2), restLength, ks, amp);
        }
        else {
            if (ks > 0) {
                newLineObject = new Spring(myPointObjectBuilder.getPointObject(m1),
                        myPointObjectBuilder.getPointObject(m2), restLength, ks);
            }
            else {
                newLineObject = new Bar(myPointObjectBuilder.getPointObject(m1),
                        myPointObjectBuilder.getPointObject(m2), restLength);
            }
        }
        addToSimulation(sim, newLineObject);
    }
    
    public void addToSimulation(Simulation sim, LineObject toAdd) {
        sim.addUpdatable(toAdd);
        sim.addPaintable(toAdd);
    }
    
    public PointObjectBuilder getPointObjectBuilder() {
        return myPointObjectBuilder;
    }
}
